package com.javabase;

/**
 * @Description: java类作用描述
 * @Author: Bsea
 * @CreateDate: 2019/6/3$ 20:57$
 */
public class StringTest2 {
    public static void main(String[] args) {
        String s1="abc";
        String s2=new String("abc");
        //每次new都会在堆里开一个新的内存空间
        String s5=new String("abc");
        //false: s1是从常量池拿数据， s2是在堆里（只要是new就是堆）
        //1.7之前，常量池在方法区，之后在堆里，独立开了一块内存放常量池
        System.out.println("s1==s2**"+(s1==s2));
        //true: String类的equals方法被重写了，比较的是里面的值
        System.out.println(s1.equals(s2));

        System.out.println("s5==s2**"+(s5==s2));
        /**
         * intern方法的作用：
         * 它的作用是：如果运行时常量池中已经包含一个
         * 等于此String对象内容的字符串，
         * 则返回常量池中该字符串的引用；如果没有，
         * 则在常量池中创建与此 String
         * 内容相同的字符串，并返回常量池中创建的字符串的引用。
         */
        String s3=s2.intern();
        System.out.println("s1,s3都是常量池里面的***"+(s1==s3));
        System.out.println("s3是常量池里面的***s2是堆里面的**"+(s2==s3));
        //这句话创建了几个对象？
        //答案：2个
        /**
         *
         * 解释：
         *
         * 先有字符串"abcd"放入常量池，
         * 然后 new 了一份字符串"abcd"放入Java堆
         * (字符串常量"abcd"在编译期就已经确定放入常量池，
         * 而 Java 堆上的"abcd"是在运行期初始化阶段才确定)，
         * 然后 Java 栈的 str1 指向Java堆上的"abcd"。
         */
        String s4 = new String("abcd");

        String s6="a";
        String s7="b";
        //使用+拼接的，只有这个情况，jvm会把拼接的结果从常量池给
        //其他的所有情况，都是从堆里给
        String s8="a"+"b";
        String s9="ab";
        System.out.println("s8==s9***"+(s8==s9));
        String s10=new String("b");
        String s11="a"+s10;
        System.out.println("s11==s9***"+(s11==s9));
        String s12=s6+s7;
        System.out.println("s12==s9***"+(s12==s9));
        String s13="a"+s7;
        System.out.println("s13==s9***"+(s13==s9));
        String s14="ab"+"";
        System.out.println("s14==s9***"+(s14==s9));


        /**
         * 8种基本类型的包装类和常量池
         * Java 基本类型的包装类的大部分都实现了常量池技术，即Byte,Short,Integer,Long,Character,Boolean；这5种包装类默认创建了数值[-128，127]的相应类型的缓存数据，但是超出此范围仍然会去创建新的对象。
         *
         * 两种浮点数类型的包装类 Float,Double 并没有实现常量池技术
         */
        Integer a1=127;
        Integer a2=127;
        System.out.println("-128到127从常量池拿 a1==a2***"+(a1==a2));
        Integer a3=128;
        Integer a4=128;
        System.out.println("大于127从堆里拿  a3==a4***"+(a3==a4));

        Integer a5=10;
        Integer a6=new Integer(10);
        System.out.println("a5==a6***"+(a5==a6));
        Integer a7=5;
        Integer a8=new Integer(5);
        Integer a9=a7+a8;
        //包装类，计数过程中会自动拆箱成基本类型
        /*
        解释：

语句i4 == i5 + i6，因为+这个操作符不适用于Integer对象，
首先i5和i6进行自动拆箱操作，进行数值相加，即i4 == 40。
然后Integer对象无法与数值进行直接比较，所以i4自动拆箱转为int值40，
最终这条语句转为40 == 40进行数值比较
         */
        System.out.println("a5==a9***"+(a5==a9));







    }
}
